PTA数据结构题目集 第三周——栽树(二叉树等)

发表于 2020-09-05 1263 字 7 min read

文章目录
cos's avatar

cos

FE / ACG / 手工 / 深色模式强迫症 / INFP / 兴趣广泛养两只猫的老宅女 / remote

暂无目录
剑指offer day31 数学(困难)剑指offer day30 分治算法(困难)剑指offer day29 动态规划(困难)剑指offer day28 搜索与回溯算法(困难)剑指offer day27 栈与队列(困难)剑指offer day26 字符串(中等)剑指offer day25 模拟(中等)剑指offer day24 数学(中等)剑指offer day23 数学(简单)剑指offer day22 位运算(中等)剑指offer day21 位运算(简单)剑指offer day20 分治算法(中等)剑指offer day19 搜索与回溯算法(中等)剑指offer day18 搜索与回溯算法(中等)剑指offer day17 排序(中等)剑指offer day16 排序(简单)剑指offer day15 搜索与回溯算法(中等)剑指offer day14 搜索与回溯算法(中等)剑指offer day13 双指针(简单)剑指offer day12 双指针(简单)剑指offer day11 双指针(简单)剑指offer day10 动态规划(中等)剑指offer day9 动态规划(中等)剑指offer day8 动态规划(简单)剑指offer day7 搜索与回溯算法(简单)剑指offer day6 搜索与回溯算法(简单)剑指offer day5 查找算法(中等)剑指offer day4 查找算法(简单)剑指offer day3 字符串(简单)剑指offer day2 链表(简单)剑指offer day1 栈与队列(简单)冲刺春招-精选笔面试66题大通关day22冲刺春招-精选笔面试66题大通关day21冲刺春招-精选笔面试66题大通关day20冲刺春招-精选笔面试66题大通关day19冲刺春招-精选笔面试66题大通关18冲刺春招-精选笔面试66题大通关17冲刺春招-精选笔面试66题大通关16冲刺春招-精选笔面试66题大通关day15冲刺春招-精选笔面试66题大通关day14冲刺春招-精选笔面试66题大通关day13冲刺春招-精选笔面试66题大通关day12冲刺春招-精选笔面试66题大通关day11冲刺春招-精选笔面试66题大通关day10冲刺春招-精选笔面试66题大通关day9冲刺春招-精选笔面试66题大通关day8冲刺春招-精选笔面试66题大通关day7冲刺春招-精选笔面试66题大通关day6冲刺春招-精选笔面试66题大通关day5冲刺春招-精选笔面试66题大通关day4冲刺春招-精选笔面试66题大通关day3冲刺春招-精选笔面试66题大通关day2冲刺春招-精选笔面试66题大通关day12021秋PAT乙级真题题解及赛后总结PAT乙级刷题感想及踩坑总结PTA数据结构题目集 第三周——栽树(二叉树等)PTA数据结构题目集 第十一周——散列查找PTA数据结构题目集 第十周——排序(下)PTA数据结构题目集 第九周——排序(上)PTA数据结构题目集 第八周——图(下)PTA数据结构题目集 第七周——图(中)PTA数据结构题目集 第六周——图(上)PTA数据结构题目集 第五周——堆&哈夫曼树&并查集PTA数据结构题目集 第四周——二叉搜索树&二叉平衡树PTA数据结构题目集 第二周——线性结构PTA数据结构题目集 第一周——最大子列和算法、二分查找MOOC浙大数据结构课后题记录——PTA数据结构题目集(全)2020蓝桥杯省模拟赛题目记录

题目集总目录 学习指路博客 二叉树队列

03-树 1 树的同构 (25 分)

本题链接

小白专场会做详细讲解,基本要求,一定要做 >题目大意:给定两棵树,请你判断它们是否是同构的。

思路

1.二叉树的表示 数组存储结构体,结构体含数据、左右孩子的下标(Null 代表-1)2.建二叉树 返回根节点下标 3.同构判断 利用递归。若 R1、R2 同时为空,返回 true。若其中一个为空,返回 false。若根节点元素就不相同,则返回 false。然后进行左右子树的判断,若两个左子树都为空,则判断右子树是否同构。若两个左子树都不为空且元素相同,不用交换直接判断,否则交换判断。

代码

#include <iostream>
using namespace std;
#define maxsize 11
#define Null -1
typedef int Tree;
struct TNode {
    char data;
    Tree left,right;
}T1[maxsize], T2[maxsize];
Tree BuildTree(struct TNode T[]){
    int N,root;
    char l,r;
    bool isroot[maxsize];
    root = Null;
    scanf("%d", &N);
    if(N) {
        for(int i = 0; i < N; ++i) isroot[i] = true;
        getchar();
        for(int i = 0; i < N; ++i) {
            scanf("%c %c %c", &T[i].data, &l, &r);
            getchar();
            if(l != '-') {
                T[i].left = l -'0';
                isroot[T[i].left] = false;
            } else T[i].left = Null;
            if(r != '-') {
                T[i].right = r -'0';
                isroot[T[i].right] = false;
            } else T[i].right = Null;
        }
        for(int i = 0; i < N; ++i)
            if(isroot[i]) {
                root = i;
                break;
            }
    }
    return root;
}
bool judge(Tree R1, Tree R2) {
    if(R1 == Null && R2 == Null)
        return true;    //两个都为空
    if((R1 == Null && R2 != Null) || (R1 != Null && R2 == Null))
        return false;   //其中一个为空
    if(T1[R1].data != T2[R2].data)
        return false;   //根节点元素就不一样
    //两个左子树都为空,则判断右子树是否同构
    if(T1[R1].left == Null && T2[R2].left == Null)
        return judge(T1[R1].right, T2[R2].right);
    //两个左子树都不为空且元素相同,不用交换
    if((T1[R1].left != Null) && (T2[R2].left != Null)
            && (T1[T1[R1].left].data == T2[T2[R2].left].data))
        return judge(T1[R1].left, T2[R2].left) &&
            judge(T1[R1].right, T2[R2].right);
    else {//交换左右子树,判断
        return judge(T1[R1].left, T2[R2].right) &&
               judge(T1[R1].right, T2[R2].left);
    }
}
int main() {
    Tree R1, R2;
    R1 = BuildTree(T1);
    R2 = BuildTree(T2);
    if(judge(R1, R2))
        cout << "Yes" << endl;
    else cout << "No" << endl;
    return 0;
}

测试点

测试点如下 在这里插入图片描述

03-树 2 List Leaves (25 分)

本题链接

训练建树和遍历基本功,一定要做

题目大意

给定一棵树,你应该按自上而下的顺序列出所有的叶子结点,从左到右。

思路

按自上到下,从左往右的顺序输出叶子结点的,则需要进行层次遍历,整体代码与 3-1 大致相同

#include <iostream>
#include <queue>
using namespace std;
#define maxsize 11
#define Null -1
typedef int Tree;
int cnt;
struct TNode {
    int data;
    Tree left,right;
}T1[maxsize];
Tree BuildTree(struct TNode T[]){
    int N,root;
    char l,r;
    bool isroot[maxsize];
    root = Null;
    scanf("%d", &N);
    if(N) {
        for(int i = 0; i < N; ++i) isroot[i] = true;
        getchar();
        for(int i = 0; i < N; ++i) {
            scanf("%c %c", &l, &r);
            getchar();
            if(l != '-') {
                T[i].left = l -'0';
                isroot[T[i].left] = false;
            } else T[i].left = Null;
            if(r != '-') {
                T[i].right = r -'0';
                isroot[T[i].right] = false;
            } else T[i].right = Null;
        }
        for(int i = 0; i < N; ++i)
            if(isroot[i]) {
                root = i;
                break;
            }
    }
    return root;
}
void LevelOrderTraversal(Tree R) {
    queue<Tree> q; //保存暂不访问的节点
    if(R == Null) return;
    q.push(R);
    while(!q.empty()) {
        Tree R1 = q.front();
        q.pop();
        if(T1[R1].left == Null && T1[R1].right == Null) {//为叶子结点
            if(cnt != 0) {
                printf(" %d", R1);
            } else printf("%d",R1);
            cnt++;
        }
        if(T1[R1].left != Null) {
            q.push(T1[R1].left);
        }
        if(T1[R1].right != Null) {
            q.push(T1[R1].right);
        }
    }

}
int main() {
    int N;
    Tree R1, R2;
    R1 = BuildTree(T1);
    LevelOrderTraversal(R1);
    return 0;
}

测试点如下,一次过 在这里插入图片描述

03-树 3 Tree Traversals Again (25 分)

本题链接

是 2014 年秋季 PAT 甲级考试真题,稍微要动下脑筋,想通了其实程序很基础,建议尝试

题目大意

给定 push 序列和 pop 序列即该二叉树的先序遍历和中序遍历序列,求后序遍历序列

思路

可用递归实现!先将两个序列搞出来,还原一棵二叉树,再进行后序遍历。

#include <iostream>
#include <stack>
#include <queue>
using namespace std;
#define maxsize 35
#define Null -1
int N, x, pcnt,icnt,cnt;
typedef int Tree;
struct TNode {
    int data;
    Tree left,right;
}T1[maxsize];
string o;
stack<char> s;
int c2i(char ch) {
    return ch - '0';
}
Tree Rebuild(string pre,string in) {  //已知前序和中序,求这棵树
    Tree R;
    if(pre.empty() && in.empty()) return Null;
    R = c2i(pre[0]);
    int l, r, Rindex,len;
    len = pre.length();
    Rindex = in.find(pre[0],0); //中序遍历中根节点的下标
    l = Rindex;  //左子树序列的长度
    r = len - 1 - Rindex;  //右子树序列的长度
    if (Rindex != 0)     //存在左子树
        T1[R].left = Rebuild(pre.substr(1,l), in.substr(0, l));
    else T1[R].left = Null;
    if (Rindex != len-1)   //存在右子树
        T1[R].right = Rebuild(pre.substr(Rindex + 1, r), in.substr(Rindex + 1, r));
    else T1[R].right = Null;
    return R;
}
void PostOrderTraversal(Tree R) {
    if (R == Null) return;
    PostOrderTraversal(T1[R].left);
    PostOrderTraversal(T1[R].right);
    if(cnt == 0) cout << R;
    else cout << " " << R;
    cnt++;
}
int main() {
    string preod,inod;
    char ch;
    cin >> N;
    getchar();
    int n = 2*N;
    for(int i = 0; i < n; ++i) {
        cin >> o;
        if(o == "Push") {   //前序
            cin >> x;
            ch = x + '0';
            s.push(ch);
            preod = preod + ch;
        } else {    //中序
            inod = inod + s.top();
            s.pop();
        }
        getchar();
    }
    Tree R1;
    R1 = Rebuild(preod, inod);
    PostOrderTraversal(R1);
    cout << endl;
    return 0;
}

测试点

测试点如下 在这里插入图片描述

先使用 Remark42 作为临时评论系统,样式等有待优化

409k
35:31
184
使用字体寒蝉全圆体 · 感谢 字图 CDN 提供中文字体公益服务
© 2020 - 2025 cos @cosine
Powered by theme astro-koharu · Inspired by Shoka